/**
 * Copyright 2019-2022 Huawei Technologies Co., Ltd
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef INFRA_OM_STATS_LOG_MANAGER_H
#define INFRA_OM_STATS_LOG_MANAGER_H

#include <mutex>
#include <string>
#include <vector>
#include <map>
#include <thread>
#include <condition_variable>

#include "infra/om/stats/ai_stats_log_common.h"

namespace hiai {
// 对engine提供的日志写接口
// 每个engine只有一个日志写入实例，每个实例有一个缓冲区
// 每个engine将日志写入各自的缓冲区，当缓冲区满了之后，将缓冲区写入AiStatsLogFileWriter
class AiStatsLogWriter {
public:
    AiStatsLogWriter();
    virtual ~AiStatsLogWriter() = default;
    virtual void Write(AiStatsData& item, AiStatsEngineType type);
    virtual void DeleteLogFile(AiStatsEngineType type);
    virtual void WriteToFile(AiStatsEngineType type);
    virtual void Write(AiStatsData& item) = 0; // 对engine提供写日志的接口
    virtual void DeleteLogFile() = 0; // 定时器超时时，需要负责多余日志的删除
    virtual void WriteToFile() = 0; // 定时器超时时，需要负责将buffer里面的日志写入文件
    void WriteToFileSync(AiStatsEngineType type);
private:
    // 容量有最大值控制:MAX_LOG_BUFFER_SIZE
    std::map<pid_t, std::map<std::string, AiStatsData>> logBuffer_;
    int logBufferSize_ = 0;
    std::mutex logBufferLock_; // 写buffer或者写文件锁,保护mLogBuffer
    std::mutex deleteFileLock_; // 写文件锁
};

class AiMMStatsLogWriter : public AiStatsLogWriter {
public:
    static AiMMStatsLogWriter* GetInstance();
    void Write(AiStatsData& item) override;
    void WriteToFile() override;
    void DeleteLogFile() override;
    void AddVersion(AiStatsData& item);

private:
    AiMMStatsLogWriter() = default;
    ~AiMMStatsLogWriter() override
    {
        WriteToFileSync(AI_STATS_HIAI_MNGR);
    };
    std::map<pid_t, std::vector<AiStatsData>> waitProcessName_;
    std::mutex waitProcessNameLock_;
    std::string ddkVersion_;
};

class AiHiAiEngineStatsLogWriter : public AiStatsLogWriter {
public:
    static AiHiAiEngineStatsLogWriter* GetInstance();
    void Write(AiStatsData& item) override;
    void WriteToFile() override;
    void DeleteLogFile() override;
    void AddVersion(AiStatsData& item);

private:
    AiHiAiEngineStatsLogWriter() = default;
    ~AiHiAiEngineStatsLogWriter() override
    {
        WriteToFileSync(AI_STATS_HIAI_ENGINE);
    };
};

class AiANNStatsLogWriter : public AiStatsLogWriter {
public:
    static AiANNStatsLogWriter* GetInstance();
    void Write(AiStatsData& item) override;
    void WriteToFile() override;
    void DeleteLogFile() override;
    void AddVersion(AiStatsData& item);

private:
    AiANNStatsLogWriter() = default;
    ~AiANNStatsLogWriter() override
    {
        WriteToFileSync(AI_STATS_ANN);
    };
    std::string ddkVersion_;
};

class AiHiAiHCSStatsLogWriter : public AiStatsLogWriter {
public:
    static AiHiAiHCSStatsLogWriter* GetInstance();
    void Write(AiStatsData& item) override;
    void WriteToFile() override;
    void DeleteLogFile() override;
    void AddVersion(AiStatsData& item);

private:
    AiHiAiHCSStatsLogWriter() = default;
    ~AiHiAiHCSStatsLogWriter() override
    {
        WriteToFileSync(AI_STATS_HIAI_HCS);
    };
};

class AiHiAiDDKStatsLogWriter : public AiStatsLogWriter {
public:
    static AiHiAiDDKStatsLogWriter* GetInstance();
    void Write(AiStatsData& item) override;
    void WriteToFile() override;
    void DeleteLogFile() override;
    void AddVersion(AiStatsData& item);

private:
    AiHiAiDDKStatsLogWriter() = default;
    ~AiHiAiDDKStatsLogWriter() override
    {
        WriteToFileSync(AI_STATS_HIAI_DDK);
    };
    std::string ddkVersion_;
};
} // end namespace hiai
#endif // INFRA_OM_STATS_LOG_MANAGER_H
